const { resolve } = require('path');
const webpack = require('webpack');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyPlugin = require('copy-webpack-plugin');

const staticPath = resolve(__dirname, 'pydata_sphinx_theme', 'static');

const vendor = resolve(staticPath, 'vendor');
const vendorVersions = {
  fontAwesome: require('@fortawesome/fontawesome-free/package.json').version,
  openSans: require('@openfonts/open-sans_all/package.json').version,
  lato: require('@openfonts/lato_latin-ext/package.json').version,
};
const vendorPaths = {
  fontAwesome: resolve(vendor, 'fontawesome', vendorVersions.fontAwesome),
  openSans: resolve(vendor, 'open-sans_all', vendorVersions.openSans),
  lato: resolve(vendor, 'lato_latin-ext', vendorVersions.lato),
};

// generates cache-busting templates to be used in `layout.html` without knowing versions
function macroTemplate({ compilation }) {
  const indexes = Object.keys(compilation.assets).filter(
    (file) => file.indexOf('/index.') != -1
  );

  const css = indexes.filter((file) => file.endsWith('.css'));
  const js = indexes.filter((file) => file.endsWith('.js'));

  const stylesheet = (css) => {
    return `\
<link href="{{ pathto('_static/css/theme.css', 1) }}" rel="stylesheet" />
  <link href="{{ pathto('_static/${css}', 1) }}" rel="stylesheet" />`;
  };

  const preload = (js) => {
    return `<link rel="preload" as="script" href="{{ pathto('_static/${js}', 1) }}">`;
  };

  const script = (js) => {
    return `<script src="{{ pathto('_static/${js}', 1) }}"></script>`;
  };

  return `<!-- these macros are generated by "yarn build:production". do not edit by hand. -->
{% macro head_pre_icons() %}
  <link rel="stylesheet"
    href="{{ pathto('_static/vendor/fontawesome/${
      vendorVersions.fontAwesome
    }/css/all.min.css', 1) }}">
  <link rel="preload" as="font" type="font/woff2" crossorigin
    href="{{ pathto('_static/vendor/fontawesome/${
      vendorVersions.fontAwesome
    }/webfonts/fa-solid-900.woff2', 1) }}">
  <link rel="preload" as="font" type="font/woff2" crossorigin
    href="{{ pathto('_static/vendor/fontawesome/${
      vendorVersions.fontAwesome
    }/webfonts/fa-brands-400.woff2', 1) }}">
{% endmacro %}

{% macro head_pre_fonts() %}
  <link rel="stylesheet"
    href="{{ pathto('_static/vendor/open-sans_all/${
      vendorVersions.openSans
    }/index.css', 1) }}">
  <link rel="stylesheet"
    href="{{ pathto('_static/vendor/lato_latin-ext/${
      vendorVersions.lato
    }/index.css', 1) }}">
{% endmacro %}

{% macro head_pre_bootstrap() %}
  ${css.map(stylesheet).join('\n')}
{% endmacro %}

{% macro head_js_preload() %}
  ${js.map(preload).join('\n')}
{% endmacro %}

{% macro body_post() %}
  ${js.map(script).join('\n')}
{% endmacro %}`;
}

module.exports = {
  entry: {
    index: ['./src/js/index.js'],
  },
  output: {
    filename: 'js/[name].[hash].js',
    path: staticPath,
  },
  externals: {
    // Define jQuery as external, this way Sphinx related javascript
    // and custom javascript like popper.js can hook into jQuery.
    jquery: 'jQuery',
  },
  module: {
    rules: [
      {
        test: /\.scss$/,
        use: [
          {
            loader: 'file-loader',
            options: {
              name: 'css/[name].[hash].css',
            },
          },
          {
            loader: 'extract-loader',
          },
          {
            loader: 'css-loader?-url',
          },
          {
            loader: 'sass-loader',
          },
        ],
      },
    ],
  },
  plugins: [
    new CleanWebpackPlugin({
      cleanOnceBeforeBuildPatterns: ['**/*', '!css', '!css/theme.css'],
    }),
    new HtmlWebpackPlugin({
      filename: resolve(staticPath, 'webpack-macros.html'),
      inject: false,
      minify: false,
      css: true,
      templateContent: macroTemplate,
    }),
    new CopyPlugin([
      // fontawesome
      {
        context: './node_modules/@fortawesome/fontawesome-free',
        from: 'LICENSE.txt',
        to: resolve(vendorPaths.fontAwesome, 'LICENSE.txt'),
      },
      {
        context: './node_modules/@fortawesome/fontawesome-free/css',
        from: 'all.min.css',
        to: resolve(vendorPaths.fontAwesome, 'css'),
      },
      {
        context: './node_modules/@fortawesome/fontawesome-free',
        from: 'webfonts',
        to: resolve(vendorPaths.fontAwesome, 'webfonts'),
      },
      // opensans
      {
        context: './node_modules/@openfonts/open-sans_all',
        from: 'files/*-400*',
        flatten: true,
        to: resolve(vendorPaths.openSans, 'files'),
      },
      {
        context: './node_modules/@openfonts/open-sans_all',
        from: 'LICENSE.md',
        to: resolve(vendorPaths.openSans, 'LICENSE.md'),
      },
      {
        context: './node_modules/@openfonts/open-sans_all',
        from: 'index.css',
        to: resolve(vendorPaths.openSans, 'index.css'),
      },
      // lato
      {
        context: './node_modules/@openfonts/lato_latin-ext',
        from: 'files/*',
        flatten: true,
        to: resolve(vendorPaths.lato, 'files'),
      },
      {
        context: './node_modules/@openfonts/lato_latin-ext',
        from: 'LICENSE.md',
        to: resolve(vendorPaths.lato, 'LICENSE.md'),
      },
      {
        context: './node_modules/@openfonts/lato_latin-ext',
        from: 'index.css',
        to: resolve(vendorPaths.lato, 'index.css'),
      },
    ]),
  ],
};
